import inspect

import requests
from rest_framework import exceptions
from rest_framework.exceptions import ValidationError
from rest_framework.views import exception_handler

from testview.settings import otherHost, REQUEST_TOKEN
from testview.settings import DEBUG


def getData(request):
    f_name = inspect.getframeinfo(inspect.currentframe().f_back)[2]
    if f_name == 'get':
        return request.query_params
    elif f_name in ['post', 'put', 'delete']:
        return request.data
    else:
        return None
    # print(f_name)
    # return

# 未知错误响应处理， 包括验证失败的处理，其他自定义 APIException
def custom_exception_handler(exc, context):
    # 重新定义
    response = exception_handler(exc, context)
    # 对具体报错的兼容
    if isinstance(exc, ValidationError):
        response.data['code'] = response.status_code
        response.data['data'] = []
        if isinstance(response.data, dict):
            response.data['msg'] = list(dict(response.data).values())[0][0]

            for key in dict(response.data).keys():
                if key not in ['code', 'data', 'message']:
                    response.data.pop(key)
        else:
            response.data['msg'] = '输入有误'
        return response

    if response is not None:
        message = response.data["detail"]
        response.data.clear()
        # response.data['code'] = response.status_code
        response.data['code'] = 400
        response.data['msg'] = None
        response.data['data'] = None

        if response.status_code == 404:
            try:
                response.data['msg'] = response.data.pop('detail')
                response.data['msg'] = "error"
            except KeyError:
                response.data['msg'] = message
                # response.data['data'] = "未找到"
        if response.status_code == 400:
            response.data['msg'] = message
            # response.data['data'] =

        elif response.status_code == 401:
            response.data['msg'] = message
            # response.data['data'] = message

        elif response.status_code >= 500:
            # print("执行")

            response.data['msg'] = message
            # response.data['data'] = "服务器错误"

        elif response.status_code == 403:
            response.data['msg'] = message
            # response.data['data'] = message

        elif response.status_code == 405:
            response.data['msg'] = message
            # response.data['data'] = message
        else:
            response.data['msg'] = message

    return response


# 这个函数是一个只返回对象键值的函数，用于对象传入多余参数的直接调用，核心内容 字典取交集,有优化空间
def data2ObjDict(data_dict, model_obj):
    return {key: None if data_dict[key] == "" else data_dict[key] for key in data_dict.keys() & model_obj.__dict__.keys()}


# 基于上面的函数进行封装,添加多的键值对，也可以在接口请求的时候在前端完善，后端不在做处理
def data2ObjDictFor(data_dict, model_obj, **dicts):
    data = data2ObjDict(data_dict, model_obj)
    for key in dicts:
        data[key] = dicts[key]
    return data


def requestData(method, path, data):
    data["token"] = REQUEST_TOKEN
    url = otherHost + path
    return requestDataFromUrl(method, url, data)


def requestDataFromUrl(method, url, data):
    try:
        if method == "post":
            result = requests.post(url, data=data)
        else:
            result = requests.get(url, params=data)
        print(result.status_code)
        if result.status_code != 200:
            raise Exception('网络请求错误')
        return result.json()
    except Exception as e:
        if DEBUG:
            print("向计算或三方服务器请求发生未知错误" + str(e))
        raise exceptions.APIException("向计算或三方服务器请求发生未知错误:" + str(e))
